package com.qike.duola.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.qike.duola.domain.*;
import com.qike.duola.dto.*;
import com.qike.duola.enums.*;
import com.qike.duola.mapper.*;
import com.qike.duola.service.*;
import com.qike.duola.utils.TimeTool;
import com.qike.duola.vo.*;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: Eric.zhou
 * @Date: 2020/9/27 11:52
 */
@Service
public class TrainServiceImpl implements TrainService {

    private static final Logger logger = LoggerFactory.getLogger(TrainServiceImpl.class);

    @Autowired
    private DuolaTrainMapper trainMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private DuolaTrainUserMapper trainUserMapper;
    @Autowired
    private IsysUserService userService;
    @Autowired
    private DuolaDeptService duolaDeptService;
    @Autowired
    private DuolaMessageService duolaMessageService;


    /**
     * 培训列表模型
     *
     * @param trainListDto
     * @return
     */
    @Override
    public TrainListVo trainList(TrainListDto trainListDto) {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "培训列表" + JSON.toJSON(trainListDto));
        DuolaTrainExample example = new DuolaTrainExample();
        DuolaTrainExample.Criteria criteria = example.createCriteria();
        if (!StringUtils.isEmpty(trainListDto.getTitle())) {
            criteria.andTitleLike(trainListDto.getTitle());
        }
        if (trainListDto.getAddTime() != null) {
            criteria.andAddTimeEqualTo(TimeTool.LongToLocalDateTime(trainListDto.getAddTime()));
        }
        Map<Long, String> userMap = new HashMap<>();
        List<SysUser> sysUsers = sysUserMapper.selectByExample(new SysUserExample());
        for (SysUser sysUser : sysUsers) {
            userMap.put(sysUser.getId(), sysUser.getNickname());
        }
        TrainListVo vo = new TrainListVo();
        List<TrainList> list = new ArrayList<>();
        example.setOrderByClause("add_time desc");
        Page page = PageHelper.startPage(trainListDto.getStartPage(), trainListDto.getPageSize());
        List<DuolaTrain> duolaTrains = trainMapper.selectByExample(example);
        for (DuolaTrain duolaTrain : duolaTrains) {
            TrainList trainList = new TrainList();
            trainList.setId(duolaTrain.getId());
            trainList.setAddress(duolaTrain.getAddress());
            trainList.setAddTime(TimeTool.LocalDateTimeFormat(duolaTrain.getStartTime()));
            trainList.setEndTime(TimeTool.LocalDateTimeFormat(duolaTrain.getEndTime()));
            trainList.setAddTime(TimeTool.LocalDateTimeFormat(duolaTrain.getAddTime()));
            trainList.setRemark(duolaTrain.getRemark());
            trainList.setTrainStatus(duolaTrain.getTrainStatus());
            DuolaTrainUserExample trainUserExample = new DuolaTrainUserExample();
            trainUserExample.createCriteria().andTrainIdEqualTo(duolaTrain.getId()).andIsFixEqualTo(StatusEnums.NO.getEcode());
            List<DuolaTrainUser> duolaTrainUsers = trainUserMapper.selectByExample(trainUserExample);
            StringBuilder names = new StringBuilder();
            for (DuolaTrainUser duolaTrainUser : duolaTrainUsers) {
                names.append("," + userMap.get(duolaTrainUser.getUid()));
            }
            trainList.setFixUser(names.toString());
            list.add(trainList);
        }
        vo.setList(list);
        vo.setTotal(page.getTotal());
        return vo;
    }

    /**
     * 添加培训
     *
     * @param addTrainDto
     */
    @Override
    @Transactional
    public void addTrain(AddTrainDto addTrainDto) throws IOException {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "添加培训" + JSON.toJSON(addTrainDto));
        DuolaTrain duolaTrain = new DuolaTrain();
        duolaTrain.setAddTime(LocalDateTime.now());
        duolaTrain.setAddUid(userId);
        duolaTrain.setAddress(addTrainDto.getAddress());
        duolaTrain.setStartTime(TimeTool.LongToLocalDateTime(addTrainDto.getStartTime()));
        duolaTrain.setEndTime(TimeTool.LongToLocalDateTime(addTrainDto.getEndTime()));
        duolaTrain.setPhoto(addTrainDto.getImage());
        duolaTrain.setRemark(addTrainDto.getRemark());
        duolaTrain.setTrainStatus(addTrainDto.getIsSend());
        duolaTrain.setStatus(StatusEnums.NO.getEcode());
        trainMapper.insertSelective(duolaTrain);
        if (addTrainDto.getFixUId() != null && addTrainDto.getFixUId().size() > 0) {
            for (Long uid : addTrainDto.getFixUId()) {
                DuolaTrainUser duolaTrainUser = new DuolaTrainUser();
                duolaTrainUser.setAddTime(LocalDateTime.now());
                duolaTrainUser.setUid(uid);
                duolaTrainUser.setTrainId(duolaTrain.getId());
                duolaTrainUser.setIsFix(StatusEnums.NO.getEcode());
                duolaTrainUser.setStatus(StatusEnums.NO.getEcode());
                trainUserMapper.insertSelective(duolaTrainUser);
            }
        }
        //todo 给所有人发布活动信息
        duolaMessageService. allUserMsgAdd(duolaTrain.getId(), MessageTitleEnums.ACTIVE.getEmsg(),userId,MessageTypeEnums.active.getEcode());


    }

    /**
     * 培训详情
     *
     * @param id
     * @return
     */
    @Override
    public TrainInfoVo trainInfo(Integer id) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "培训详情" + JSON.toJSON(id));
        DuolaTrain duolaTrain = trainMapper.selectByPrimaryKey(id);
        if (duolaTrain == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        TrainInfoVo vo = new TrainInfoVo();
        vo.setAddress(duolaTrain.getAddress());
        vo.setImage(duolaTrain.getPhoto());
        vo.setIsSend(duolaTrain.getTrainStatus());
        vo.setTitle(duolaTrain.getTitle());
        vo.setStartTime(TimeTool.LocalDateTimeFormat(duolaTrain.getStartTime()));
        vo.setEndTime(TimeTool.LocalDateTimeFormat(duolaTrain.getEndTime()));
        vo.setRemark(duolaTrain.getRemark());
        DuolaTrainUserExample trainUserExample = new DuolaTrainUserExample();
        trainUserExample.createCriteria().andIsFixEqualTo(StatusEnums.NO.getEcode()).andTrainIdEqualTo(id);
        List<DuolaTrainUser> duolaTrainUsers = trainUserMapper.selectByExample(trainUserExample);
        List<Long> uids = new ArrayList<>();
        for (DuolaTrainUser duolaTrainUser : duolaTrainUsers) {
            uids.add(duolaTrainUser.getUid());
        }
        vo.setFixUId(uids);
        if (uids.size() > 0) {
            List<String> names = new ArrayList<>();
            SysUserExample example = new SysUserExample();
            example.createCriteria().andIdIn(uids);
            List<SysUser> sysUsers = sysUserMapper.selectByExample(example);
            for (SysUser sysUser : sysUsers) {
                names.add(sysUser.getNickname());
            }
            vo.setNames(names);
        }

        return vo;
    }

    /**
     * 培训编辑
     *
     * @param trainEditDto
     */
    @Override
    public void trainEdit(TrainEditDto trainEditDto) {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "培训编辑" + JSON.toJSON(trainEditDto));
        DuolaTrain duolaTrain = new DuolaTrain();
        duolaTrain.setId(trainEditDto.getId());
        duolaTrain.setAddress(trainEditDto.getAddress());
        duolaTrain.setStartTime(TimeTool.LongToLocalDateTime(trainEditDto.getStartTime()));
        duolaTrain.setEndTime(TimeTool.LongToLocalDateTime(trainEditDto.getEndTime()));
        duolaTrain.setPhoto(trainEditDto.getImage());
        duolaTrain.setRemark(trainEditDto.getRemark());
        duolaTrain.setTrainStatus(trainEditDto.getIsSend());
        duolaTrain.setStatus(StatusEnums.NO.getEcode());
        trainMapper.updateByPrimaryKeySelective(duolaTrain);
        DuolaTrainUserExample example = new DuolaTrainUserExample();
        example.createCriteria().andTrainIdEqualTo(duolaTrain.getId()).andIsFixEqualTo(StatusEnums.NO.getEcode());
        trainUserMapper.deleteByExample(example);
        if (trainEditDto.getFixUId() != null && trainEditDto.getFixUId().size() > 0) {
            for (Long uid : trainEditDto.getFixUId()) {
                DuolaTrainUser duolaTrainUser = new DuolaTrainUser();
                duolaTrainUser.setUid(uid);
                duolaTrainUser.setAddTime(LocalDateTime.now());
                duolaTrainUser.setUid(uid);
                duolaTrainUser.setTrainId(duolaTrain.getId());
                duolaTrainUser.setIsFix(StatusEnums.NO.getEcode());
                duolaTrainUser.setStatus(StatusEnums.NO.getEcode());
                trainUserMapper.insertSelective(duolaTrainUser);
            }


        }
    }

    /**
     * 发布培训/取消发布
     *
     * @param trainOpenOrCloseDto
     */
    @Override
    public void trainOpenOrClose(TrainOpenOrCloseDto trainOpenOrCloseDto) {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "发布培训/取消发布" + JSON.toJSON(trainOpenOrCloseDto));
        DuolaTrain duolaTrain = trainMapper.selectByPrimaryKey(trainOpenOrCloseDto.getId());
        duolaTrain.setTrainStatus(trainOpenOrCloseDto.getStatus());
        trainMapper.updateByPrimaryKeySelective(duolaTrain);
    }

    /**
     * 删除培训
     *
     * @param trainDelDto
     */
    @Override
    public void trainDel(TrainDelDto trainDelDto) {
        DuolaTrain duolaTrain = trainMapper.selectByPrimaryKey(trainDelDto.getId());
        duolaTrain.setStatus(StatusEnums.YES.getEcode());
        trainMapper.updateByPrimaryKeySelective(duolaTrain);
    }

    /**
     * 参加培训
     *
     * @param trainJoinDto
     */
    @Override
    public void trainJoin(TrainJoinDto trainJoinDto) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "参加培训" + JSON.toJSON(trainJoinDto));
        DuolaTrain duolaTrain = trainMapper.selectByPrimaryKey(trainJoinDto.getId());
        if (duolaTrain == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        DuolaTrainUserExample example = new DuolaTrainUserExample();
        example.createCriteria().andTrainIdEqualTo(trainJoinDto.getId()).andUidEqualTo(userId).andStatusEqualTo(StatusEnums.NO.getEcode());
        List<DuolaTrainUser> duolaTrainUsers = trainUserMapper.selectByExample(example);
        if (duolaTrainUsers.size() > 0) {
            throw new Exception(ErrorEnums.CANT_JOIN_TRAIN.getEmsg());
        }
        DuolaTrainUser duolaTrainUser = new DuolaTrainUser();
        duolaTrainUser.setUid(userId);
        duolaTrainUser.setAddTime(LocalDateTime.now());
        duolaTrainUser.setStatus(StatusEnums.NO.getEcode());
        duolaTrainUser.setIsFix(StatusEnums.YES.getEcode());
        duolaTrainUser.setTrainId(trainJoinDto.getId());
        trainUserMapper.insertSelective(duolaTrainUser);
        //todo 参加后给用户发送消息
    }

    /**
     * 取消培训
     *
     * @param trainCancelDto
     */
    @Override
    public void trainCancel(TrainCancelDto trainCancelDto) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "取消培训" + JSON.toJSON(trainCancelDto));
        DuolaTrain duolaTrain = trainMapper.selectByPrimaryKey(trainCancelDto.getId());
        if (duolaTrain == null) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        DuolaTrainUserExample example = new DuolaTrainUserExample();
        example.createCriteria().andTrainIdEqualTo(trainCancelDto.getId()).andUidEqualTo(userId).andStatusEqualTo(StatusEnums.NO.getEcode());
        List<DuolaTrainUser> duolaTrainUsers = trainUserMapper.selectByExample(example);
        if (duolaTrainUsers.size() <= 0) {
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        DuolaTrainUser duolaTrainUser = duolaTrainUsers.get(0);
        duolaTrainUser.setStatus(StatusEnums.NO.getEcode());
        trainUserMapper.insertSelective(duolaTrainUser);
    }

    /**
     * 参与名单
     *
     * @param id
     * @return
     */
    @Override
    public List<TrainUserListVo> trainUserList(Integer id) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "参与名单" + JSON.toJSON(id));
        List<TrainUserListVo> voList = new ArrayList<>();
        //获取所有人员
        List<SysUser> allUser = userService.getAllUser(null);
        Map<Long, SysUser> userMap = new HashMap<>();
        for (SysUser sysUser : allUser) {
            userMap.put(sysUser.getId(), sysUser);
        }

        DuolaTrainUserExample trainUser = new DuolaTrainUserExample();
        trainUser.createCriteria().andTrainIdEqualTo(id).andStatusEqualTo(StatusEnums.NO.getEcode());
        List<DuolaTrainUser> duolaTrainUsers = trainUserMapper.selectByExample(trainUser);
        for (DuolaTrainUser duolaTrainUser : duolaTrainUsers) {
            TrainUserListVo vo = new TrainUserListVo();
            vo.setId(duolaTrainUser.getId());
            vo.setIsFix(duolaTrainUser.getIsFix());
            vo.setScore(duolaTrainUser.getScore());
            vo.setUserName(userMap.get(duolaTrainUser.getUid()) == null ? userMap.get(duolaTrainUser.getUid()).getNickname() : null);
            vo.setDeptName(userMap.get(duolaTrainUser.getUid()) == null ? duolaDeptService.getDeptById(userMap.get(duolaTrainUser.getUid()).getDeptId()).getDeptName() : null);
            voList.add(vo);
        }
        return voList;
    }

    /**
     * 参与名单编辑
     *
     * @param trainUserEditDto
     */
    @Override
    public void trainUserEdit(TrainUserEditDto trainUserEditDto) {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId + "参与名单编辑" + JSON.toJSON(trainUserEditDto));
        List<TrainUserEdit> list = trainUserEditDto.getList();
        for (TrainUserEdit trainUserEdit : list) {
            DuolaTrainUser duolaTrainUser = new DuolaTrainUser();
            duolaTrainUser.setId(trainUserEdit.getId());
            duolaTrainUser.setScore(trainUserEdit.getScore());
            trainUserMapper.updateByPrimaryKeySelective(duolaTrainUser);
        }
    }
}
